package com.mandala.service;

import static org.springframework.ldap.query.LdapQueryBuilder.query;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.naming.NamingEnumeration;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.ldap.odm.annotations.Attribute;
import org.springframework.ldap.query.LdapQuery;
import org.springframework.stereotype.Service;

import com.mandala.LDAPConnectService;
import com.mandala.attributeMapper.RoleAttributeMapper;
import com.mandala.entry.ApplicationSystem;
import com.mandala.entry.Group;
import com.mandala.entry.Org;
import com.mandala.entry.Permission;
import com.mandala.entry.Role;
import com.mandala.entry.User;
import com.mandala.utils.QueryUtil;
import com.mandala.utils.StringUtil;

@Service
public class OdmUserRepo {
	@Autowired
	private LdapTemplate ldapTemplate;
	
	public User create(User user) {
		ldapTemplate.create(user);
		return user;
	}
	
	//通过用户id查询用户信息
	public User findUserByCn(String cn) {
		//主要是担心查询的结果不唯一而导致报错，所以需要使用list,然后取第一个
		List<User> userList = new ArrayList<User>();
		try {
			userList = ldapTemplate.find(query().base("ou=user").where("cn").is(cn).and("isDelete").is("false").and("status").is("true"), User.class);
			if(userList.size() >0){
				return userList.get(0);
			}else{
				return null;
			}
		} catch (Exception e) {
			return null;
		}
		
		
	}
	//通过用户工号查询用户信息
	public User findUserByUid(String uid) {
		LdapQuery query = query().base("ou=user")// .attributes("ou") //返回的属性
				.where("uid").is(uid)// 查询条件
				.and("isDelete").is("false").and("status").is("true");
		//主要是担心查询的结果不唯一而导致报错，所以需要使用list,然后取第一个
		List<User> userList = new ArrayList<User>();
		try {
			userList = ldapTemplate.find(query, User.class);
			if(userList.size() >0){
				return userList.get(0);
			}else{
				return null;
			}
		} catch (Exception e) {
			return null;
		}
		
	}
	//查询所有用户列表
	public List<User> findAllUser() {
		LdapQuery query = query().base("ou=user").where("objectclass").is("person").and("isDelete").is("false").and("status").is("true");// base
																					// -
																					// 指定搜索应在其中开始的LDAP树中的根ou=user
		return (List<User>) ldapTemplate.find(query, User.class);
	}
	//通过群组id查询群组信息
	public Group findGroupByCn(String cn) {
		LdapQuery query = query().base("ou=group")// .attributes("ou") //返回的属性
				.where("cn").is(cn)// 查询条件
				.and("isDelete").is("false").and("status").is("true");
		Group group = new Group();
		try {
			group = ldapTemplate.findOne(query, Group.class);
		} catch (Exception e) {
			return null;
		}
		
		return group;
		//return ldapTemplate.findOne(query().base("ou=group").where("cn").is(cn), Group.class);
	}
	//通过用户的id查询用户绑定的群组列表（这个方法太复杂，暂时不用）
	public List<Group> findGroupByUserId(String member) {
		List<Group> list = findAllGroup();
		int result = list.size();
		if (result > 0) {
			Iterator<Group> it = list.iterator();
			while (it.hasNext()) {
				List<String> memberString = findGroupByCn(it.next().getCn()).getMember();// 获取每个群组的成员信息
				if (memberString.size() > 0) {
					Boolean flag = false;// 判断该群组中是否存在该用户
					for (int i = 0; i < memberString.size(); i++) {
						//System.out.println(memberString.get(i));
						// cn=defaultUser,ou=user,dc=xiehe,dc=com 这是获取到的成员信息
						//System.out.println("是否包含=" + (memberString.get(i)).contains("cn=" + member));
						if ((memberString.get(i).split(",")[0]).equals("cn=" + member)) {
							flag = true;
							break;
						}
					}
					if (!flag) {
						it.remove();
					}

				} else {// 没有成员信息，说明该用户不在该群组下，移除该群组
					it.remove();
				}
			}
			return list;

		} else {
			return null;
		}

	}
	//通过用户的id查询用户所绑定的群组，但是这个方法没有使用，暂时只作为参考使用
	public void getGroupByUserId(String member) {
		String conditions = "cn=" + member + ",ou=user,dc=xiehe,dc=com";
		// 创建搜索控件
		SearchControls searchCtls = new SearchControls();
		// 设置搜索范围
		searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
		// 设置搜索过滤条件
		String searchFilter = "(&(objectclass=groupOfNames)(member=" + conditions +"))" ;
		// 设置搜索域节点
		String searchBase = "ou=group";
		// 定制返回属性
		String returnedAtts[] = { "cn" };
		//searchCtls.setReturningAttributes(returnedAtts);
		// 不定制属性，返回所有的属性集
		searchCtls.setReturningAttributes(null);
		DirContext dc = ldapTemplate.getContextSource().getReadOnlyContext();
		try {
			NamingEnumeration<SearchResult> en = dc.search(searchBase, searchFilter, searchCtls);
			if (en == null) {
				System.out.println("Have no NamingEnumeration.");
			}
			if (!en.hasMoreElements()) {
				System.out.println("Have no element.");
			}
			// Loop through the search results
			while (en.hasMoreElements()) {
				SearchResult entry = en.next();
				System.out.println(">>>" + entry.getName());
				// Print out the groups
				Attributes attrs = entry.getAttributes();
				if (attrs != null) {
					for (NamingEnumeration<? extends Attribute> names = (NamingEnumeration<? extends Attribute>) attrs.getAll(); names.hasMore();) {
						Attribute attr = names.next();
						for (NamingEnumeration<?> e = ((Attributes) attr).getAll(); e.hasMore();) {
							System.out.println("Attributes:" + e.next());
						}
					}
				}
			}
			System.out.println("Search complete.");
		} catch (Exception e) {
			System.out.println("Exception in search():" + e);
		}

	}
	
	//通过用户id查询用户绑定的群组列表
	public List<Group> findAllGroupByUserId(String member) {
		String conditions = QueryUtil.getUserQueryCondition(member);//"cn=" + member + ",ou=user,dc=xiehe,dc=com";
		LdapQuery query = query().base("ou=group").where("objectclass").is("groupOfNames")
				.and("member").is(conditions).and("isDelete").is("false").and("status").is("true");// base
		return (List<Group>) ldapTemplate.find(query, Group.class);
	}
	
	//通过用户的工号查询用户绑定的角色列表,这个方法只能查询用户绑定的系统角色，并不能查出用户绑定的动态和静态角色
	public List<Role> findAllRoleByUserCode(String userCode) {
		String conditions = QueryUtil.getUserQueryCondition(userCode);//"cn=" + userCode + ",ou=user,dc=xiehe,dc=com";
		LdapQuery query = query().base("ou=role").where("objectclass").is("groupOfURLs")
				.and("user").is(conditions).and("isDelete").is("false").and("status").is("true");// base
		return (List<Role>) ldapTemplate.find(query, Role.class);
	}
	
	//通过用户的id查询用户绑定的业务系统列表
	public List<ApplicationSystem> findAllSystemByUserId(String member) {
		String conditions = QueryUtil.getUserQueryCondition(member);//"cn=" + member + ",ou=user,dc=xiehe,dc=com";
		LdapQuery query = query().base("ou=system").where("objectclass").is("groupOfNames")
				.and("member").is(conditions).and("isDelete").is("false").and("status").is("true");// base
		return (List<ApplicationSystem>) ldapTemplate.find(query, ApplicationSystem.class);
	}

	//通过组织机构的id查询组织机构的信息
	public Org findOrgByOu(String ou) {
		Org org = new Org();
		try {
			org = ldapTemplate.findOne(query().base("ou=org").where("ou").is(ou).and("isDelete").is("false").and("status").is("true"), Org.class);
		} catch (Exception e) {
			return null;
		}
		
		return org;
		
	}
	
	//通过用户工号查询组织机构的信息
	public List<Role> findRoleByUserCode(String userCode) {
		String condition = QueryUtil.getUserQueryCondition(userCode);
		List<Role> roleList = new ArrayList<>();
		try {
			roleList = ldapTemplate.find(query().base("ou=role").where("user").is(condition).and("isDelete").is("false").and("status").is("true"), Role.class);
		} catch (Exception e) {
			return null;
		}
		
		return roleList;
		
	}
	
	//通过组织机构ID查询组织机构的信息
	public List<Role> findRoleByOrgId(String id) {
		String condition = QueryUtil.getOrgQueryCondition(id);
		List<Role> roleList = new ArrayList<>();
		try {
			roleList = ldapTemplate.find(query().base("ou=role").where("org").is(condition).and("isDelete").is("false").and("status").is("true"), Role.class);
		} catch (Exception e) {
			return null;
		}
		
		return roleList;
		
	}
	
	//通过群组ID查询组织机构的信息
	public List<Role> findRoleByGroupId(String id) {
		String condition = QueryUtil.getGroupQueryCondition(id);
		List<Role> roleList = new ArrayList<>();
		try {
			roleList = ldapTemplate.find(query().base("ou=role").where("group").is(condition).and("isDelete").is("false").and("status").is("true"), Role.class);
		} catch (Exception e) {
			return null;
		}
		
		return roleList;
		
	}
	
	
	//通过角色id查询角色的详细信息
	public Role findRoleByCn(String cn) {
		Role role = new Role();
		try {
			role = ldapTemplate.findOne(query().base("ou=role").where("cn").is(cn).and("isDelete").is("false").and("status").is("true"), Role.class);
		} catch (Exception e) {
			return null;
		}
		
		return role;
	}

	//通过应用系统的id查询应用系统的详细信息
	public ApplicationSystem findApplicationSystemByCn(String cn) {
		ApplicationSystem system = new ApplicationSystem();
		try {
			system = ldapTemplate.findOne(query().base("ou=system").where("cn").is(cn).and("isDelete").is("false").and("status").is("true"), ApplicationSystem.class);
		} catch (Exception e) {
			return null;
		}
		
		return system;
	}

	//通过权限id查询权限的详细信息
	public Permission findPermissionByOu(String ou) {
		Permission permission = new Permission();
		try {
			permission = ldapTemplate.findOne(query().base("ou=permission").where("ou").is(ou).and("isDelete").is("false").and("status").is("true"), Permission.class);
		} catch (Exception e) {
			return null;
		}
		
		return permission;
		//return ldapTemplate.findOne(query().base("ou=permission").where("ou").is(ou), Permission.class);
	}
	
	//通过权限id和systemId查询权限的详细信息
	public Permission findPermissionByOuAndSystemId(String ou,String systemId) {
		Permission permission = new Permission();
		LdapQuery query = query().base("ou=permission").where("ou").is(ou).and("systemId").is(systemId).and("status").is("true").and("isDelete")
				.is("false");
		try {
			permission = ldapTemplate.findOne(query, Permission.class);
		} catch (Exception e) {
			return null;
		}
		return permission;
	}
	
	//通过业务系统的id查询该业务系统所具有的权限列表
	public List<Permission> findPermissionBySystemId(String systemId) {
		LdapQuery query = query().base("ou=permission").where("objectclass").is("organizationalUnit").and("status").is("true").and("isDelete")
				.is("false").and("systemId").is(systemId);// base - 指定搜索应在其中开始的LDAP树中的根ou=org。
		return (List<Permission>) ldapTemplate.find(query, Permission.class);
	}

	//查询所有的组织机构列表
	public List<Org> findAllOrg() {
		LdapQuery query = query().base("ou=org").where("objectclass").is("organizationalUnit").and("isDelete")
				.is("false").and("status").is("true");// base - 指定搜索应在其中开始的LDAP树中的根ou=org。
		return (List<Org>) ldapTemplate.find(query, Org.class);
	}

	//查询所有的群组列表
	public List<Group> findAllGroup() {
		LdapQuery query = query().base("ou=group").where("objectclass").is("groupOfNames")
				.and("isDelete").is("false").and("status").is("true");// base// 指定搜索应在其中开始的LDAP树中的根ou=group。
		return (List<Group>) ldapTemplate.find(query, Group.class);
	}

	//查询所有的角色列表
	public List<Role> findAllRole() {
		LdapQuery query = query().base("ou=role").where("objectclass").is("groupOfURLs")
				.and("isDelete").is("false").and("status").is("true");// base指定搜索应在其中开始的LDAP树中的根ou=role。
		return (List<Role>) ldapTemplate.find(query, Role.class);
	}

	//查询所有的应用系统列表
	public List<ApplicationSystem> findAllApplicationSystem() {
		LdapQuery query = query().base("ou=system").where("objectclass").is("groupOfNames")
				.and("isDelete").is("false").and("status").is("true");// base 指定搜索应在其中开始的LDAP树中的根ou=system。
		return (List<ApplicationSystem>) ldapTemplate.find(query, ApplicationSystem.class);
	}

	public User modifyPerson(User user) {
		ldapTemplate.update(user);
		return user;
	}

	public void deletePerson(User user) {
		ldapTemplate.delete(user);
	}
	
	public List<Permission> findPermissionByConditions(User user, String systemId) {
		
		List<Role> roleList = findRoleByConditions(user);
		List<Permission> listPermission = new ArrayList<>();
		if(roleList.size()>0){
			listPermission = findPermissionByRole(roleList,systemId);
		}
		
		return listPermission;
	}

	//静态角色，静态角色和系统角色查询方法
	@SuppressWarnings("unchecked")
	public List<Role> findRoleByConditions(User user) {
		StringBuffer  searchFilter = new StringBuffer("(");
		// 设置搜索过滤条件
		searchFilter.append("&(objectclass=groupOfURLs)"+QueryUtil.getSameQueryCondition()) ;
		String usercondition = QueryUtil.getUserQueryCondition(user.getCn());
		searchFilter.append("(|(user=" + usercondition +")") ;
		//得到用户关联的组织机构id
        List<String> ouList = user.getOu();
        if(ouList.size() > 0 ){
        	for (int i = 0; i < ouList.size(); i++) {
        		String orgcondition = QueryUtil.getOrgQueryCondition(ouList.get(i));
        		searchFilter.append("(org=" + orgcondition +")") ;
			}
        }
        String cn = user.getCn();
        //通过用户的id来查询用户绑定的群组
        List<Group> listGroup = findAllGroupByUserId(cn);
        if(listGroup.size()>0){
        	for (int i = 0; i < listGroup.size(); i++) {
        		String groupcondition = QueryUtil.getGroupQueryCondition(listGroup.get(i).getCn());
        		searchFilter.append("(group=" + groupcondition +")") ;
			}
        }
        
        searchFilter.append("))") ;
		List<Role> roleList = new ArrayList<>();
		
		/*AndFilter andFilter = new AndFilter();
		andFilter.and(new EqualsFilter("objectclass", "groupOfURLs"));
		andFilter.and(new EqualsFilter("user", usercondition));*/
		// 设置搜索域节点
		String searchBase = "ou=role";
		
		roleList = ldapTemplate.search(searchBase, searchFilter.toString(),new RoleAttributeMapper());
		//动态角色查询方法
		List<Role> roleList2 = findRoleByUserConditions(user);
		if(roleList2.size()>0){
			//两个list合并
			roleList.addAll(roleList2);
		}
		//得到的list,如果有subRole,还需要根据subRole来查询角色
		if(roleList.size()>0){
			for (int i = 0; i < roleList.size(); i++) {
				if(roleList.get(i).getSubRole() != null){
					List<String> subRoleList = roleList.get(i).getSubRole();
					for (int j = 0; j < subRoleList.size(); j++) {
						String subRoleCn = subRoleList.get(j).split(",")[0].substring(3);
						Role subRole = findRoleByCn(subRoleCn);
						if(subRole != null){
							roleList.add(subRole);
						}
					}
				}
			}
			
		}
		List<Role> newRoleList = new ArrayList<>();
		//对于list<Role> 也要去重复
		roleList.stream().filter(StringUtil.distinctByKey(p -> p.getCn())).forEach(p -> newRoleList.add(p));
		//List<Permission> listPermission = findPermissionByRole(roleList,systemId);
		return newRoleList;
	}
	
	//通过用户动态角色来查看用户的权限，比如某个职称所具有的权限
	public List<Role> findRoleByUserConditions(User user){
		StringBuffer  searchFilter = new StringBuffer("(");
		// 设置搜索过滤条件
		searchFilter.append("&(objectclass=groupOfURLs)"+QueryUtil.getSameQueryCondition()) ;
		String btrtlName = user.getBtrtlName();//
		if(btrtlName != null){
			searchFilter.append("(|(code=btrtlName=" + btrtlName +")") ;
		}
		String employeeNature = user.getEmployeeNature();
		if(employeeNature != null){
			searchFilter.append("(code=employeeNature=" + employeeNature +")") ;
		}
		String jobStatus = user.getJobStatus();
		if(jobStatus != null){
			searchFilter.append("(code=jobStatus=" + jobStatus +")") ;
		}
		String techTitle = user.getTechTitle();
		if(techTitle != null){
			searchFilter.append("(code=techTitle=" + techTitle +")") ;
		}
		String techTitle1 = user.getTechTitle1();
		if(techTitle1 != null){
			searchFilter.append("(code=techTitle1=" + techTitle1 +")") ;
		}
		String techTitle2 = user.getTechTitle2();
		if(techTitle2 != null){
			searchFilter.append("(code=techTitle2=" + techTitle2 +")") ;
		}
		String techLevel = user.getTechLevel();
		if(techLevel != null){
			searchFilter.append("(code=techLevel=" + techLevel +")") ;
		}
		searchFilter.append("))") ;
		List<Role> roleList = new ArrayList<>();
		// 设置搜索域节点
		String searchBase = "ou=role";
		
		roleList = ldapTemplate.search(searchBase, searchFilter.toString(),new RoleAttributeMapper());
		return roleList;
	}
	
	public List<Permission> findPermissionByRole(List<Role> listRole,String systemId){
		//定义List<String>类型，专门存放权限id的
		List<String> permissionOuList = new ArrayList<>();
		if(listRole.size() > 0){
			for (int i = 0; i < listRole.size(); i++) {
				//获取角色绑定的权限列表
				//System.out.println("角色名称："+listRole.get(i).getResourceName());
				List<String> rolePermissionCnList = listRole.get(i).getPermission();
				if(rolePermissionCnList != null && rolePermissionCnList.size()>0){
					for (int j = 0; j < rolePermissionCnList.size(); j++) {
						//截取权限列表中的权限id
						String ou = rolePermissionCnList.get(j).split(",")[0].substring(3);
						permissionOuList.add(ou);
					}
				}
			}
		}
		//System.out.println("权限id="+permissionOuList);
		//对于List<String>  去重复的权限id
		permissionOuList = StringUtil.removeDuplicate3(permissionOuList);
		//System.out.println("去重复之后的权限id="+permissionOuList);
		//根据权限id去查询权限
		List<Permission> listPermission = new ArrayList<>();
		if(permissionOuList.size()>0){
			for (int j = 0; j < permissionOuList.size(); j++) {
				Permission permission = findPermissionByOuAndSystemId(permissionOuList.get(j),systemId);
				//如果通过权限id查询出来的权限存在，就存放到list中
				if(permission != null){
					listPermission.add(permission);
				}
				
			}
		}
		return listPermission;
		
	}
}
